home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Utilities / Winter Shell 1.0d2 / Source / Libraries / RadioLib / RadioLib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-13  |  4.1 KB  |  178 lines  |  [TEXT/KAHL]

  1. /*    handle radio button groups
  2.     93/12/23 aih - added frame and title rectangles
  3.     93/12/18 aih - made more memory efficient by eliminating linked list
  4.     93/11/07 aih - created */
  5.     
  6. #include "ControlLib.h"
  7. #include "DrawLib.h"
  8. #include "EventLib.h"
  9. #include "MemoryLib.h"
  10. #include "RadioLib.h"
  11. #include "RectangleLib.h"
  12. #include "WindowLib.h"
  13.  
  14. /* return i'th item in radio button list */
  15. #define ITEM(radio, i) (((RadioItemType *) (*radio + 1))[i])
  16.  
  17. Boolean RadioValid(RadioHandle radio)
  18. {
  19.     if (! HandleValidSize(radio, sizeof(RadioType))) return(false);
  20.     if (HandleSize(radio) != sizeof(RadioType) +
  21.             sizeof(RadioItemType) * (**radio).nitems)
  22.     {
  23.         return(false);
  24.     }
  25.     return(true);
  26.     
  27. }
  28.  
  29. RadioHandle RadioBegin(WindowPtr window, const Rect *frame, const Rect *title)
  30. {
  31.     volatile RadioHandle radio = NULL;
  32.     RgnHandle rgn = NULL;
  33.     
  34.     require(! frame || RectValid(frame));
  35.     require(! title || RectValid(title));
  36.     TRY {
  37.         radio = HandleBeginClear(sizeof(RadioType));
  38.         rgn = NewRgn(); FailNIL(rgn); (**radio).saveClip = rgn;
  39.         rgn = NewRgn(); FailNIL(rgn); (**radio).clipRgn = rgn;
  40.         (**radio).window = window;
  41.         if (frame) (**radio).frame = *frame;
  42.         if (title) (**radio).title = *title;
  43.         WinRegister(window, radio, RadioEventTable());
  44.     } CATCH {
  45.         RadioEnd(radio);
  46.     } ENDTRY;
  47.     ensure(RadioValid(radio));
  48.     return(radio);
  49. }
  50.  
  51. void RadioEnd(RadioHandle radio)
  52. {
  53.     if (radio) {
  54.         WinUnregister((**radio).window, radio);
  55.         if ((**radio).clipRgn) DisposeRgn((**radio).clipRgn);
  56.         if ((**radio).saveClip) DisposeRgn((**radio).saveClip);
  57.         HandleEnd(radio);
  58.         radio = NULL;
  59.     }
  60.     ensure(! RadioValid(radio));
  61. }
  62.  
  63. void RadioAdd(RadioHandle radio, ControlHandle ctl, short id)
  64. {
  65.     require(RadioValid(radio));
  66.     WinUnregister(CtlWindow(ctl), ctl);
  67.     HandleSizeSet(radio, sizeof(RadioType) +
  68.         ((**radio).nitems + 1) * sizeof(RadioItemType));
  69.     ITEM(radio, (**radio).nitems).ctl = ctl;
  70.     ITEM(radio, (**radio).nitems).id = id;
  71.     (**radio).nitems++;
  72.     ensure(RadioValid(radio));
  73. }
  74.  
  75. ControlHandle RadioSelected(RadioHandle radio)
  76. {
  77.     require(RadioValid(radio));
  78.     return((**radio).item.ctl);
  79. }
  80.  
  81. short RadioSelectedID(RadioHandle radio)
  82. {
  83.     require(RadioValid(radio));
  84.     return((**radio).item.id);
  85. }
  86.  
  87. void RadioClick(RadioHandle radio, ControlHandle ctl)
  88. {
  89.     short i;
  90.         
  91.     require(RadioValid(radio));
  92.     if (ctl != RadioSelected(radio)) {
  93.         for (i = 0; i < (**radio).nitems; i++) {
  94.             RadioItemType item = ITEM(radio, i);
  95.             CtlValueSet(item.ctl, item.ctl == ctl);
  96.             if (item.ctl == ctl)
  97.                 (**radio).item = item;
  98.         }
  99.     }
  100. }
  101.  
  102. void RadioClickID(RadioHandle radio, short id)
  103. {
  104.     short i;
  105.         
  106.     require(RadioValid(radio));
  107.     if (id != RadioSelectedID(radio)) {
  108.         for (i = 0; i < (**radio).nitems; i++) {
  109.             RadioItemType item = ITEM(radio, i);
  110.             CtlValueSet(item.ctl, item.id == id);
  111.             if (item.id == id)
  112.                 (**radio).item = item;
  113.         }
  114.     }
  115. }
  116.  
  117. void RadioUpdate(RadioHandle radio)
  118. {
  119.     GrafPtr port = NULL;
  120.     PenState pen;
  121.     Rect frame, title;
  122.     
  123.     require(RadioValid(radio));
  124.     frame = (**radio).frame;
  125.     title = (**radio).title;
  126.     if (! EmptyRect(&frame)) {
  127.         GetPort(&port);
  128.         SetPort((**radio).window);
  129.         GetPenState(&pen);
  130.         PenPat(gray);
  131.         if (! EmptyRect(&title)) {
  132.             /* exclude title rectangle */
  133.             RectRgn((**radio).clipRgn, &frame);
  134.             RectRgn((**radio).saveClip, &title);
  135.             DiffRgn((**radio).clipRgn, (**radio).saveClip, (**radio).clipRgn);
  136.             GetClip((**radio).saveClip);
  137.             SetClip((**radio).clipRgn);
  138.         }
  139.         FrameRect(&frame);
  140.         if (! EmptyRect(&title))
  141.             SetClip((**radio).saveClip);
  142.         SetEmptyRgn((**radio).clipRgn);
  143.         SetEmptyRgn((**radio).saveClip);
  144.         SetPenState(&pen);
  145.         SetPort(port);
  146.     }
  147. }
  148.  
  149. Boolean RadioWithin(RadioHandle radio, Point where)
  150. {
  151.     Boolean within = false;
  152.     short i;
  153.     
  154.     require(RadioValid(radio));
  155.     for (i = 0; ! within && i < (**radio).nitems; i++)
  156.         within = CtlWithin(ITEM(radio, i).ctl, where);
  157.     return(within);
  158. }
  159.  
  160. Boolean RadioMouseDown(RadioHandle radio, EventRecord *event)
  161. {
  162.     ControlHandle ctl = NULL;
  163.     short part = 0;
  164.     Point where;
  165.     
  166.     require(RadioValid(radio));
  167.     where = event->where;
  168.     GlobalToPort(&where, (**radio).window);
  169.     check(RadioWithin(radio, where));
  170.     part = FindControl(where, (**radio).window, &ctl);
  171.     if (part) {
  172.         part = TrackControl(ctl, where, NULL);
  173.         if (part)
  174.             RadioClick(radio, ctl);
  175.     }
  176.     return(part != 0);
  177. }
  178.